home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / autofill / autofill.pas next >
Pascal/Delphi Source File  |  1995-12-22  |  4KB  |  191 lines

  1. {Please find below source code for the simple auto fill component. This has -not- 
  2. been thoroughly tested, and I can accept no liability for it <g>. Hope it is of 
  3. interest. Please feel free to do with it what you wish, but please let me know 
  4. what you think.
  5.  
  6. Regards
  7. Phil
  8. }
  9.  
  10. {Unit Combo: Simple 'Auto Fill' Combo Box
  11. To Use: Add this as a control using options menu from Delphi
  12. Written by Phil Arundell (phil@pacom.demon.co.uk)
  13. This file is placed in the public domain
  14.  
  15.  
  16. implementation note: 
  17. As this control uses a binary search, it only works on SORTED combo boxes, 
  18. which is set as the default
  19.  
  20. }
  21.  
  22. unit Combo;
  23.  
  24. interface
  25.  
  26. uses
  27.   SysUtils,
  28.   WinTypes,
  29.   WinProcs,
  30.   Messages,
  31.   Classes,
  32.   Graphics,
  33.   Controls,
  34.   Forms,
  35.   Dialogs,
  36.   StdCtrls;
  37.  
  38. type
  39.   TExtCombo = class(TComboBox)
  40.   private
  41.     { Private declarations }
  42.   protected
  43.     { Protected declarations }
  44.     function BinarySearch(StringToFind: String): String;
  45.     procedure KeyPress(var Key: Char); override;
  46.   public
  47.     { Public declarations }
  48.     constructor Create(AOwner: TComponent); override;
  49.   published
  50.     { Published declarations }
  51.     property Sorted default True;
  52.   end;
  53.  
  54. procedure Register;
  55.  
  56. implementation
  57.  
  58.  
  59.  
  60. procedure Register;
  61. begin
  62.   RegisterComponents('Samples', [TExtCombo]);
  63. end;
  64.  
  65. constructor TExtCombo.Create(AOwner: TComponent);
  66. begin
  67.   inherited Create(AOwner);
  68.   Sorted := True;
  69. end;
  70.  
  71.  
  72.  
  73. procedure TExtCombo.KeyPress(var Key: Char);
  74. var
  75.     Temp, ListText, MatchString: String;
  76.    startpos, second, TextLen: Integer;
  77.  
  78. begin
  79.    Inherited KeyPress (Key);
  80.  
  81.    if key in [#8,#27,#13,#9] then
  82.       exit;
  83.  
  84.    temp := '';
  85.    startpos := SelStart;
  86.    second := startPos + SelLength + 1 ;
  87.    if startpos <> 0 then
  88.       temp := copy(Text,0, startpos);
  89.  
  90.    temp := temp + Key +
  91.                Copy(Text, second, Length(Text) - Second + 1);
  92.    TextLen:= Length(Temp);
  93.  
  94.  
  95.    MatchString := BinarySearch(Temp);
  96.  
  97.    if MatchString <> '' Then
  98.    begin
  99.       Text := MatchString;
  100.       SelStart := StartPos + 1;
  101.       SelLength := length(ListText) - StartPos -1;
  102.    end
  103.    else
  104.    begin
  105.       Text := Temp;
  106.       SelStart := StartPos + 1;
  107.    end;
  108.    key := #0;
  109.  
  110. end;
  111.  
  112.  
  113. function TExtCombo.BinarySearch(StringToFind: String): String;
  114. var
  115.     curpos: Integer;
  116.    MaxPos: Integer;
  117.    MinPos: Integer;
  118.    ItemCount: Integer;
  119.     IncAmount: Integer;
  120.    len: integer;
  121.    Temp: String;
  122.  
  123. begin
  124.     MaxPos := Items.Count -1;
  125.    MinPos := 0;
  126.     len := Length(StringToFind);
  127.     result := '';
  128.    {exit if no items in Items, or search string < lowest value or > highest 
  129. value}
  130.    if (maxpos = -1) or
  131.            (CompareText(StringToFind,Copy(Items[0],0,len)) <0) or
  132.              (CompareText(StringToFind,Copy(Items[MaxPos],0,Len)) > 
  133. 0) then
  134.              exit;
  135.  
  136.     {special case for matching last string, go backwards through Items
  137.    until earliest match is found}
  138.    If CompareText(StringToFind, Copy(Items[MaxPos],0,Len)) = 0 Then
  139.    begin
  140.         while ((CompareText(StringToFind, Copy(Items[MaxPos],0,Len))= 0) 
  141. and (maxpos <>0)) do
  142.             dec (maxpos);
  143.  
  144.        inc (MaxPos);
  145.           Result := Items[MaxPos];
  146.       exit;
  147.    end;
  148.     {special case for matching first string, exit if match found}
  149.    If CompareText(StringToFind, Copy(Items[0],0,Len)) = 0 Then
  150.    begin
  151.         Result := Items[0];
  152.       exit;
  153.    end;
  154.  
  155.    curpos := MaxPos Div 2;
  156.     {main binary search loop}
  157.     while (abs(MaxPos - MinPos)<> 1) and (MaxPos <= ItemCount) Do
  158.    begin
  159.         temp := Items[CurPos];
  160.         case CompareText(StringToFind,Copy(Temp,0,Len)) of
  161.          -32767..-1:
  162.          begin
  163.             MaxPos := curpos;
  164.          end;
  165.  
  166.           0:
  167.          begin
  168.              result := Items[CurPos];
  169.             exit;
  170.          end;
  171.  
  172.          1..32767:
  173.          begin
  174.             MinPos := CurPos;
  175.          end;
  176.  
  177.       end;
  178.  
  179.       CurPos := MinPos + ((MaxPos - MinPos) Div 2);
  180.       end;
  181. end;
  182.  
  183.  
  184. end.
  185.  
  186. {end of file}
  187.  
  188.  
  189. { Phil Arundell (phil@pacom.demon.co.uk) }
  190.  
  191.